package com.wireless.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

import wireless.test.MyLogger;

/**
 * chargeDevice service thread,connect to all chargeDevice
 * put chargeDevice into chargeDeviceRepo
 * @author fang.junpeng
 *
 */
public class ChargeService implements Runnable {
	
	volatile boolean bStop=false;
	private ServerSocket serverSocket=null;
	private static ChargeService chargeService=null;
	private boolean isActive = false;
	@SuppressWarnings("unused")
	private ChargeDeviceRepo chargeDeviceRepo=null;//keep a reference of ChargeDeviceRepo Object
	private int serverPORT=8989;
	private MyLogger logger=null;
	
	private ChargeService() {
		chargeDeviceRepo = ChargeDeviceRepo.getInstance();//get chargeDevice repo at first
		logger = MyLogger.getInstance();
	}
	
	public static ChargeService getInstance() {
		if(chargeService == null)
			chargeService = new ChargeService();
		return chargeService;
	}
	/**
	 * start service
	 */
	public void startService(){
		new Thread(this).start();
	}
	/**
	 * stop service
	 */
	public void stopService(){
		setStop(true);
	}

	@Override
	public void run() {
		//new a serverSocket
		try {
			serverSocket = new ServerSocket(serverPORT);
			isActive = true;
		} catch (IOException e) {
			e.printStackTrace();
			logger.log("failed");
			serverSocket = null;
		}
		//check serverSocket is OK
		if(!isActive){
			logger.log("statup service thread failed!please check!");
			System.err.println("error");
			return;
		}
		Socket socket = null;
		while(!bStop){
			try {
				socket = serverSocket.accept();
				Thread workThread = new Thread(new ChargeServiceHandler(socket));
				workThread.start();//start thread
				logger.log(socket.getInetAddress()+" connected");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public void setServerPORT(int serverPORT) {
		this.serverPORT = serverPORT;
	}

	private void setStop(boolean Stop) {
		this.bStop = Stop;
	}
	
}

/**
 * get map between deviceID --- socket
 * put Map<deviceID,chargeDevice> into chargeDeviceRepo
 * @author fang.junpeng
 *
 */
class ChargeServiceHandler implements Runnable{
	private Socket socket=null;

	public ChargeServiceHandler(Socket socket) {
		this.socket = socket;
	}
	
	public ChargeServiceHandler() {
		// TODO Auto-generated constructor stub
	}
	
	public void setSocket(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		MyLogger.getInstance().log("ChargeServiceHandler");
		InputStream in=null;
		boolean bStop = false;
		char[] data = new char[255];
		while(!bStop){
			try {
				in = socket.getInputStream();
				BufferedReader reader = new BufferedReader(new InputStreamReader(in));
				reader.read(data, 0, 255);
				//String data = reader.readLine();//wait for data
				String[] decodeResult = ChargeCmd.decodeCmd(new String(data));
				if(decodeResult!=null && decodeResult.length == 2){
					if(decodeResult[0].equals(ChargeCmd.cmd_deviceID)){
						String deviceID = decodeResult[1];
						MyLogger.getInstance().log("chargeService:"+deviceID+" OK");
						//ChargeDeviceRepo.getInstance().addDevice(deviceID, new ChargeDevice(deviceID, socket));
						//for test
						synchronized (ChargeDeviceRepo.getInstance()) {
							ChargeDeviceRepo.getInstance().addDevice("hdu123456", new ChargeDevice("hdu123456", socket));
						}
						if(ChargeDeviceRepo.getInstance().findChargeDeviceByID("hdu123456")==null)
							MyLogger.getInstance().log("find err");
						
						bStop = true;//thread stop when get map between deviceID ---- socket
						MyLogger.getInstance().log("created a new charge device");
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
		
}
